package ma.ac.onousc.gestionfi.budget.model.DAO.DAOBean;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import ma.ac.onousc.gestionfi.budget.model.DAO.GenericDAO;

public abstract class GenericEJB3Bean<T, ID extends Serializable> implements
		GenericDAO<T, ID> {

	private Class<T> entityBeanType;

	// PersistenceContext injection
	@PersistenceContext(unitName = "fi-onousc-back")
	private EntityManager em;

	@SuppressWarnings("unchecked")
	public GenericEJB3Bean() {
		this.entityBeanType = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

	protected EntityManager getEntityManager() {
		if (em == null)
			throw new IllegalStateException(
					"EntityManager has not been set on DAO before usage, please check that and try again...");
		return em;
	}

	public Class<T> getEntityBeanType() {
		return entityBeanType;
	}

	public T findById(ID id) {
		return getEntityManager().find(getEntityBeanType(), id);
	}

	@SuppressWarnings("unchecked")
	public List<T> findAll() {
		String query = "select o from " + getEntityBeanType().getSimpleName()
				+ " o ";
		return getEntityManager().createQuery(query).getResultList();
	}

	public T makePersistent(T entity) {
		return getEntityManager().merge(entity);
	}

	public void makeTransient(T entity) {
		// first we should merge the entity and remove it after
		getEntityManager().remove(getEntityManager().merge(entity));
	}

	public void flush() {
		getEntityManager().flush();
	}

	public void clear() {
		getEntityManager().clear();
	}

	public void refresh(T entity) {
		getEntityManager().refresh(entity);
	}

}
